package cn.tnar.parkservice.service.impl;


import ch.qos.logback.core.joran.util.beans.BeanUtil;
import cn.tnar.parkservice.config.Constant;
import cn.tnar.parkservice.mapper.AccessRuleMapper;
import cn.tnar.parkservice.model.dto.AccessRuleDTO;
import cn.tnar.parkservice.model.dto.AccessRuleDetail;
import cn.tnar.parkservice.model.entity.*;
import cn.tnar.parkservice.model.response.AccessRuleResponse;
import cn.tnar.parkservice.service.*;
import cn.tnar.parkservice.util.DtoUtil;
import cn.tnar.parkservice.util.IDUtils;
import cn.tnar.parkservice.util.common.ResultCode;
import cn.tnar.parkservice.util.common.ResultJson;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: yl
 * @date 2018/9/13 15:24
 */
@Service("accessRuleServiceImpl")
@Slf4j
public class AccessRuleServiceImpl extends ServiceImpl<AccessRuleMapper, AccessRule> implements AccessRuleService {

    @Autowired
    private AccessRuleMapper accessRuleMapper;

    private ResultJson resultJson = new ResultJson();

    @Autowired
    @Qualifier("tParkRegionServiceImpl")
    private ITParkRegionService itParkRegionService;

    @Autowired
    private ITParkInfoService itParkInfoService;

    @Autowired
    @Qualifier("tParkGateServiceImpl")
    private ITParkGateService itParkGateService;

    @Autowired
    @Qualifier("tParkMemberGroupServiceImpl")
    private ITParkMemberGroupService itParkMemberGroupService;
    @Autowired
    private MqService mqService;

    @Override
    public boolean closeOtherSameGateRule(AccessRule entity) {
        return accessRuleMapper.closeOtherSameGateRule(entity);
    }

    @Override
    public Page<Map<String, Object>> queryByParkCode(String parkCode, Integer pageNo, Integer pageSize) {

        Page<Map<String, Object>> page = new Page<>(pageNo, pageSize);
        List<Map<String, Object>> list = accessRuleMapper.queryByParkCode(page, parkCode);

        for (Map<String, Object> map : list) {
            String temporary_color = map.get("temporary_color").toString();
            if (temporary_color.equals("0")) {
                map.put("color", "全部准入");
            } else if (temporary_color.equals("9")) {
                map.put("color", "全部不准入");
            } else {
                String color = temporary_color.replaceAll("1", "蓝牌")
                        .replaceAll("3", "黄牌")
                        .replaceAll("6", "绿牌")
                        .replaceAll("7", "白牌")
                        .replaceAll("8", "黑牌");

                map.put("color", color);

            }

        }
        return page.setRecords(list);
    }

    @Override
    public boolean updateIsUsing(Integer IsUsing, Long accessRuleId) {
        return accessRuleMapper.updateIsUsing(IsUsing, accessRuleId);
    }

    @Override
    public ResultJson insert(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        long itemId = IDUtils.genItemId();

        List<AccessRule> list = new ArrayList<>();

        List<Map<String, Object>> gateList = accessRuleDTO.getGateList();
        if (gateList.size() == 0) {
            return resultJson.setCode(ResultCode.FAIL).setMsg(Constant.MSG_GATECONFIG_NULL).setData(null);
        }
        for (Map<String, Object> map : gateList) {
            AccessRule entity = DtoUtil.convertObject(accessRuleDTO, AccessRule.class);
            entity.setAccessRuleId(itemId);
            entity.setRegionCode(map.get("regionCode").toString());
            entity.setAccessGate(map.get("accessGate").toString());
            entity.setStartTime(Long.valueOf(map.get("startTime").toString()));
            entity.setEndTime(Long.valueOf(map.get("endTime").toString()));
            list.add(entity);
        }

        boolean flag = this.saveBatch(list);

        if (flag) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(null);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);
        }
    }

    @Override
    public ResultJson update(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);

        List<Map<String, Object>> gateList = accessRuleDTO.getGateList();
        List<AccessRule> list = new ArrayList<>();
        for (Map<String, Object> map : gateList) {
            AccessRule accessRule = new AccessRule();
            accessRule.setRuleName(accessRuleDTO.getRuleName());
            accessRule.setId(Integer.valueOf(map.get("id").toString()));
            accessRule.setStartTime(Long.valueOf(map.get("startTime").toString()));
            accessRule.setEndTime(Long.valueOf(map.get("endTime").toString()));
            accessRule.setTemporaryColor(accessRuleDTO.getTemporaryColor());
            list.add(accessRule);
        }

        boolean flag = this.updateBatchById(list);
        if (flag) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(null);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);
        }
    }

    @Override
    public ResultJson updateYes(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        Long accessRuleId = accessRuleDTO.getAccessRuleId();
        QueryWrapper<TParkMemberGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("access_rule_id", accessRuleId);
        queryWrapper.eq("del_flag", 0);
        List<TParkMemberGroup> list = itParkMemberGroupService.list(queryWrapper);
        if (list.size() > 0) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(Constant.MSG_CONFIG_YES).setData(0);
        } else {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(Constant.MSG_CONFIG_NO).setData(1);

        }
    }

    @Override
    @Transactional
    public ResultJson delete(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        Long accessRuleId = accessRuleDTO.getAccessRuleId();

        //判断该规则是否已绑定子卡
        QueryWrapper<TParkMemberGroup> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("access_rule_id", accessRuleId);
        queryWrapper2.eq("del_flag", 0);
        List<TParkMemberGroup> list = itParkMemberGroupService.list(queryWrapper2);
        if (list.size() > 0) {
            return resultJson.setCode(ResultCode.FAIL).setMsg(Constant.MSG_CONFIG_YES).setData(0);
        }

        QueryWrapper<AccessRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("access_rule_id", accessRuleId);

        boolean flag = this.remove(queryWrapper);

        if (flag) {
            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(null);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);
        }
    }

    @Override
    public ResultJson query(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);

        Page<Map<String, Object>> mapPage = this.queryByParkCode(accessRuleDTO.getParkCode(), accessRuleDTO.getPageNo(), accessRuleDTO.getPageSize());


        return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(mapPage);
    }

    @Override
    public ResultJson queryOne(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        Long accessRuleId = accessRuleDTO.getAccessRuleId();
        //accessRuleId为access_rule_id
        QueryWrapper<AccessRule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("access_rule_id", accessRuleId);
        List<AccessRule> entitylist = this.list(queryWrapper);

        if (entitylist.size() == 0) {
            return resultJson.setCode(ResultCode.FAIL).setMsg(Constant.MSG_RULE_ERROR).setData(null);
        }
        AccessRuleDetail entity1 = DtoUtil.convertObject(entitylist.get(0), AccessRuleDetail.class);


        List<Map<String, Object>> gateList = new ArrayList<>();
        for (AccessRule accessRule : entitylist) {
            Map<String, Object> map = new HashMap<>();
            QueryWrapper<TParkRegion> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("region_code", accessRule.getRegionCode());
            TParkRegion one = itParkRegionService.getOne(queryWrapper1);
            map.put("regionCode", accessRule.getRegionCode());
            map.put("regionName", one == null ? "" : one.getName());
            gateList.add(map);
        }

        List<Map<String, Object>> collectList = gateList.stream().distinct().collect(Collectors.toList());

        for (int i = 0; i < collectList.size(); i++) {
            List<Map<String, Object>> gateList2 = baseMapper.getGateList(accessRuleId.toString(), collectList.get(i).get("regionCode").toString());
            collectList.get(i).put("gateList", gateList2);
        }
        entity1.setGateList(collectList);
        QueryWrapper<TParkInfo> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.eq("park_code", entitylist.get(0).getParkCode());
        TParkInfo one = itParkInfoService.getOne(queryWrapper3);
        entity1.setParkName(one == null ? "" : one.getName());

        String color = entity1.getTemporaryColor().replaceAll("1", "蓝牌")
                .replaceAll("3", "黄牌")
                .replaceAll("6", "绿牌")
                .replaceAll("7", "白牌")
                .replaceAll("8", "黑牌");

        entity1.setTemporaryColor(color);

        return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(entity1);

    }

    @Override
    public ResultJson configRule(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        Long groupId = accessRuleDTO.getGroupId();
        Long accessRuleId = accessRuleDTO.getAccessRuleId();
        TParkMemberGroup entity = new TParkMemberGroup();
        entity.setId(Long.valueOf(groupId));
        entity.setAccessRuleId(Long.valueOf(accessRuleId));
        boolean b = itParkMemberGroupService.updateById(entity);
        if (b) {
            TParkMemberGroup memberGroupId = itParkMemberGroupService.getById(groupId);
            QueryWrapper<AccessRule> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("access_rule_id", accessRuleId);
            List<AccessRule> list = this.list(queryWrapper);

            for (int i = 0; i < list.size(); i++) {
                String topic = "rule." + list.get(i).getParkCode();
                list.get(i).setTemporaryColor(list.get(i).getTemporaryColor().replaceAll("8", "5"));
                String jsonString = JSON.toJSONString(list.get(i));
                mqService.mqSend(jsonString, topic);
            }
            mqService.mqSend(JSON.toJSONString(memberGroupId), "memberGroup." + memberGroupId.getParkCode());

            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(null);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);

        }
    }

    @Override
    public ResultJson getRegionList(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);
        String parkCode = accessRuleDTO.getParkCode();

        QueryWrapper<TParkInfo> tParkInfoQueryWrapper = new QueryWrapper<>();
        tParkInfoQueryWrapper.eq("park_code", parkCode);
        tParkInfoQueryWrapper.eq("delflag", 1);
        TParkInfo one = itParkInfoService.getOne(tParkInfoQueryWrapper);

        List<Map<String, Object>> mapList = new ArrayList<>();

        QueryWrapper<TParkRegion> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("park_code", parkCode);
        List<TParkRegion> regionList = itParkRegionService.list(queryWrapper);

        if (regionList == null || regionList.size() == 0) {
            return resultJson.setCode(ResultCode.FAIL).setMsg(Constant.MSG_REGION_NULL).setData(null);
        }
        for (int i = 0; i < regionList.size(); i++) {
            QueryWrapper<TParkGate> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("region_code", regionList.get(i).getRegionCode());
            queryWrapper1.eq("park_code", parkCode);
            queryWrapper1.eq("gate_type", 1);
            List<TParkGate> ingateList = itParkGateService.list(queryWrapper1);

            QueryWrapper<TParkGate> queryWrapper2 = new QueryWrapper<>();
            queryWrapper2.eq("region_code", regionList.get(i).getRegionCode());
            queryWrapper2.eq("park_code", parkCode);
            queryWrapper2.eq("gate_type", 2);
            List<TParkGate> outgateList = itParkGateService.list(queryWrapper2);

            Map<String, Object> map = new HashMap<>();
            map.put("regionCode", regionList.get(i).getRegionCode());
            map.put("regionName", regionList.get(i).getName());
            map.put("parkCode", parkCode);
            map.put("parkName", one.getName());
            map.put("ingateList", ingateList);
            map.put("outgateList", outgateList);
            mapList.add(map);
        }
        return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(mapList);
    }

    @Override
    public ResultJson cancelRule(String json) {
        AccessRuleDTO accessRuleDTO = JSON.parseObject(json, AccessRuleDTO.class);

        Long groupId = accessRuleDTO.getGroupId();
        TParkMemberGroup memberGroupId = itParkMemberGroupService.getById(groupId);
        Long accessRuleId = accessRuleDTO.getAccessRuleId();
        if(memberGroupId.getAccessRuleId().longValue()!=accessRuleId.longValue()){
            return resultJson.setCode(ResultCode.FAIL).setMsg(Constant.MSG_RULE_CANCEL).setData(null);
        }

        boolean b = accessRuleMapper.updateRule(groupId);

        if (b) {
            TParkMemberGroup memberGroupIdNew = itParkMemberGroupService.getById(groupId);
            QueryWrapper<AccessRule> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("access_rule_id", accessRuleId);
            List<AccessRule> list = this.list(queryWrapper);

            for (int i = 0; i < list.size(); i++) {
                String topic = "rule." + list.get(i).getParkCode();
                list.get(i).setTemporaryColor(list.get(i).getTemporaryColor().replaceAll("8", "5"));
                AccessRuleResponse response=new AccessRuleResponse();
                response.setStatus(1);
                BeanUtils.copyProperties(list.get(i), response);

                String jsonString = JSON.toJSONString(response);
                mqService.mqSend(jsonString, topic);
            }
            mqService.mqSend(JSON.toJSONString(memberGroupIdNew), "memberGroup." + memberGroupId.getParkCode());

            return resultJson.setCode(ResultCode.SUCCESS).setMsg(ResultCode.SUCCESS_MSG).setData(null);
        } else {
            return resultJson.setCode(ResultCode.FAIL).setMsg(ResultCode.FAIL_MSG).setData(null);

        }
    }


}
